
encode(L1,L2) :-
    pack(L1,P),
    encode(P,L2,[]).
    
encode([],L2,L2):- !.
encode([X|T],L2,Acc):-
    trans(X,R1),
    optimize(R1,Acc,Acc1),
    encode(T,L2,Acc1).
    
trans([], [0,_]).
trans([X|T],[N,X]):-
    trans(T,[N1,X]),
    N is N1 +1.
    
optimize([1,A],Acc,Acc1):-!,
    append(Acc,[A],Acc1).
optimize(Z,Acc,Acc1):-
    append(Acc,[Z],Acc1).
    
% pack (+list1,-list2).
pack([],[]) :- !.
pack([X|T],L2) :-
    pack(T,L2,X,[X],[]).
    
pack([], L2, _, SubAcc,Acc) :-!,   
    append(Acc, [SubAcc], Acc1),
    L2 = Acc1.
pack([X|T], L2, H, SubAcc, Acc):-
    X == H,!,
    append(SubAcc,[X],SubAcc1),
    pack(T, L2, X, SubAcc1, Acc).   
pack([X|T], L2, H, SubAcc, Acc):-
    X \= H,!,
    append(Acc,[SubAcc],Acc1),
    pack(T, L2, X, [X], Acc1).
